package com.mxpio.erp.workshop.service.impl;

import com.mxpio.erp.common.enums.CommonEnums;
import com.mxpio.erp.common.enums.OrderEnums;
import com.mxpio.erp.common.enums.OrderStatusEnums;
import com.mxpio.erp.common.inventory.entity.InvFlow;
import com.mxpio.erp.common.plan.entity.ManufacturePlan;
import com.mxpio.erp.common.plan.service.ManufacturePlanService;
import com.mxpio.erp.common.technology.entity.Item;
import com.mxpio.erp.common.workshop.entity.OutsourceOrder;
import com.mxpio.erp.common.workshop.service.OutsourceOrderService;
import com.mxpio.erp.workshop.policy.impl.OutsourceOrderSavePolicy;
import com.mxpioframework.common.vo.Result;
import com.mxpioframework.jpa.JpaUtil;
import com.mxpioframework.jpa.policy.impl.CrudType;
import com.mxpioframework.system.service.impl.BaseServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class OutsourceOrderServiceImpl extends BaseServiceImpl<OutsourceOrder> implements OutsourceOrderService {

	@Autowired
	private OutsourceOrderSavePolicy outsourceOrderSavePolicy;
	@Autowired
	private ManufacturePlanService manufacturePlanService;

	@Override
	@Transactional
	public void handleOutsourceOrderQuantity(List<OutsourceOrder> content, String accessType) {
		Map<String, BigDecimal> quantity = new HashMap<>();
		Set<String> bizNos = JpaUtil.collectId(content);
		//1.通过InvFlow计算实际执行数量
		List<InvFlow> flows = JpaUtil.linq(InvFlow.class).in("originBizNo", bizNos).list();
		for(InvFlow flow : flows){
			//  若流水的AccessType为参数accessType 则为执行，否则为退货
			if(accessType.equals(flow.getAccessType())){
				BigDecimal actualQuantity = quantity.get("actual:"+flow.getOriginBizNo()+flow.getOriginBizLineNo());
				if(actualQuantity == null){
					actualQuantity = BigDecimal.ZERO;
				}
				actualQuantity = actualQuantity.add(flow.getQuantity());
				quantity.put("actual:"+flow.getOriginBizNo()+flow.getOriginBizLineNo(), actualQuantity);
			}else{
				BigDecimal actualRejectQuantity = quantity.get("actualReject:"+flow.getOriginBizNo()+flow.getOriginBizLineNo());
				if(actualRejectQuantity == null){
					actualRejectQuantity = BigDecimal.ZERO;
				}
				actualRejectQuantity = actualRejectQuantity.add(flow.getQuantity());
				quantity.put("actualReject:"+flow.getOriginBizNo()+flow.getOriginBizLineNo(), actualRejectQuantity);
			}
		}
		
	}
	@Override
	@Transactional//从委外计划，转换为委外订单
	public Result<Object> convertOOFromMPlan(List<ManufacturePlan> planList){
		if (planList==null || planList.size()==0){
			return Result.error("提交数据为空");
		}
		List<OutsourceOrder> addList = new ArrayList<>();
		List<String> itemCodes = planList.stream().map(ManufacturePlan::getItemCode).collect(Collectors.toList());
		List<Item> dbItems = JpaUtil.linq(Item.class).in("itemCode", itemCodes).list();
		Map<String, Item> dbItemsMap = JpaUtil.index(dbItems, "itemCode");//查询提交数据中的物料
		for (ManufacturePlan plan:planList){
			if(!CommonEnums.YesNo.YES.getCode().equals(plan.getOutsourceFlag())) {//如果不是委外计划则不生成委外订单
				continue;
			}
			OutsourceOrder order = convertFromPlan(plan,dbItemsMap);
			if (order==null){
				return Result.error("提交数据中数据不完整，物料不存在或者计划数量为空");
			}
			addList.add(order);
			try {
				manufacturePlanService.delete(ManufacturePlan.class, plan.getPlanNo());//删除计划单
			} catch (Exception e) {
				e.printStackTrace();
				return Result.error("删除原计划单时失败，可能数据已发生变化，请刷新后重试！");
			}
		}
		save(addList,outsourceOrderSavePolicy);//保存
		return Result.OK();
	}

	private OutsourceOrder convertFromPlan(ManufacturePlan plan,Map<String, Item> dbItemsMap){
		if (plan.getQuantity()==null||plan.getQuantity().compareTo(BigDecimal.ZERO)==0|| StringUtils.isBlank(plan.getItemCode())){
			return null;
		}
		Item item = dbItemsMap.get(plan.getItemCode());
		if (item==null){
			return null;
		}
		OutsourceOrder order = new OutsourceOrder();
		order.setOrderStatus(OrderStatusEnums.OrderStatus.ORDERED.getStatusCode());
		order.setCloseStatus(OrderStatusEnums.CloseStatus.OPEN.getStatusCode());
		order.setPlanner(plan.getCreateBy());
		order.setMainWorkshop(plan.getMainWorkshop());
		order.setWorkCenterCode(plan.getWorkCenterCode());
		order.setStartDate(plan.getStartDate());
		order.setEndDate(plan.getDeliverDate());
		order.setReferenceDate(new Date());//取当前日期
		order.setOrderQuantity(plan.getQuantity());
		order.setMemo(plan.getMemo());
		order.setOrderDate(new Date());

		order.setProductItemCode(item.getItemCode());
		order.setProductItemName(item.getItemName());
		order.setProductDrawingNo(item.getDrawingNo());
		order.setItemSpec(item.getItemSpec());
		order.setUnitCode(item.getUnitCode());
		order.setCrudType(CrudType.SAVE);
		order.setOrderType(OrderEnums.OutsourceOrderType.PLAN.getCode());//计划委外

		order.setPnCode(plan.getPnCode());
		order.setPnName(plan.getPnName());
		order.setBizMan(plan.getBizMan());
		return order;
	}
}
